// --------------------------------------------------------------------------------------------------------------------
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
// --------------------------------------------------------------------------------------------------------------------

namespace WP7Contrib.View.Controls.Extensions
{
    using System;
    using System.Linq;
    using System.Windows;
    using System.Windows.Input;

    using Microsoft.Phone.Reactive;

    public static class UIElementExtensions
    {
        public static IObservable<IEvent<EventArgs>> GetClick(this UIElement target)
        {
            return Observable.CreateWithDisposable<IEvent<EventArgs>>(
                observer =>
                    {
                        IObservable<IEvent<MouseButtonEventArgs>> leftDown =
                            Observable.FromEvent(
                                (EventHandler<MouseButtonEventArgs> handler) => new MouseButtonEventHandler(handler), 
                                handler => target.MouseLeftButtonDown += handler, 
                                handler => target.MouseLeftButtonDown -= handler);

                        IObservable<IEvent<MouseButtonEventArgs>> leftUp =
                            Observable.FromEvent(
                                (EventHandler<MouseButtonEventArgs> handler) => new MouseButtonEventHandler(handler), 
                                handler => target.MouseLeftButtonUp += handler, 
                                handler => target.MouseLeftButtonUp -= handler);

                        var douwnPoint = new StylusPoint();
                        int downTicks = 0;
                        return new CompositeDisposable
                            {
                                leftDown.Subscribe(
                                    @event =>
                                        {
                                            douwnPoint = @event.EventArgs.StylusDevice.GetStylusPoints(target).First();
                                            downTicks = Environment.TickCount;
                                        }), 
                                leftUp.Subscribe(
                                    @event =>
                                        {
                                            StylusPoint upPoint =
                                                @event.EventArgs.StylusDevice.GetStylusPoints(
                                                    target).First();
                                            if (
                                                Math.Sqrt(
                                                    Math.Pow(upPoint.X - douwnPoint.X, 2) +
                                                    Math.Pow(upPoint.Y - douwnPoint.Y, 2)) <=
                                                20 && Environment.TickCount - downTicks < 450)
                                            {
                                                observer.OnNext(
                                                    Event.Create<EventArgs>(target, null));
                                            }
                                        })
                            };
                    });
        }
    }
}